#ifndef TST_TESTFRAME_TEST_FRAME_H
#define TST_TESTFRAME_TEST_FRAME_H

/** 
 * @note:  在测试代码中需要向框架注册
 *      1. 测试初始化函数(通过TEST_DECLARE_INIT宏), 如不需要初始化则调用TEST_DECLARE_INIT(NULL)
 *      2. 测试清理函数(通过TEST_DECLARE_CLEANUP宏), 如不需要清理则调用TEST_DECLARE_CLEANUP(NULL)
 *      3. 测试案例函数(通过TEST_CASE宏, 第一个参数为测试案例函数指针， 第二个参数为测试案例描述)
 *  samples: 
 *         int tst_Init(void)
 *         {
 *           ...
 *         }
 *
 *         int tst_Cleanup(void)
 *         {
 *           ...
 *         }
 *
 *         int tst_TestCase1(void)
 *         {
 *             int i = 3;
 *
 *             TEST_ASSERT(1 == 2); //测试条件失败时, 退出返回-1
 *             TEST_ASSERT(i == 2, "测试失败[%d]", i); //测试条件失败时打印失败信息, 退出返回-1
 *             return 0;
 *         }
 *
 *         int tst_TestCase2(void)
 *         {
 *           ...
 *         }
 *
 *         int tst_TestCase3(void)
 *         {
 *           ...
 *         }
 *
 *         TEST_DECLARE_INIT(tst_Init)
 *         TEST_DECLARE_SUIT_BEGIN()
 *             TEST_CASE(tst_TestCase1, "测试案例1")
 *             TEST_CASE(tst_TestCase2, "测试案例2")
 *             TEST_CASE(tst_TestCase3, "测试案例3")
 *         TEST_DECLARE_SUIT_END()
 *         TEST_DECLARE_CLEANUP(tst_Cleanup)
 *
 */

#include <stdio.h>
#include <stdbool.h>

/**
 * 测试案例描述长度
 */
#define TEST_CASE_DESC_LENGTH 255

/**
 * 测试案例状态
 */
#define TEST_STATUS_STANDBY  1
#define TEST_STATUS_SUCCESS  0 
#define TEST_STATUS_FAILED  -1

typedef int (*T_TestCaseFunction)(void);
typedef int (*T_TestInitFunction)(void);
typedef int (*T_TestCleanupFunction)(void);

/**
 * 测试案例
 */
typedef struct T_TestCase_tag
{
   T_TestCaseFunction pfnTestCase;
   int                iTestReuslt;
   char               caDesc[TEST_CASE_DESC_LENGTH + 1];
} T_TestCase;

/**
 * 测试案例数组
 */
extern T_TestCase gtaTestCase[];
/**
 * 测试案例数量
 */
extern size_t gnTestCaseCount;
/**
 * 测试初始化函数
 */
extern T_TestInitFunction gpfnInit;
/**
 * 测试清理函数
 */
extern T_TestCleanupFunction gpfnCleanup;

#define TEST_DECLARE_SUIT_BEGIN() \
    T_TestCase gtaTestCase[] = {

#define TEST_DECLARE_SUIT_END()                                        \
    };                                                                 \
    size_t gnTestCaseCount = sizeof(gtaTestCase) / sizeof(T_TestCase); \

#define TEST_CASE(_pfnTestCase, _caDesc) \
    {_pfnTestCase, TEST_STATUS_STANDBY, _caDesc},

#define TEST_DECLARE_INIT(_pfnTestInit) \
    T_TestInitFunction gpfnInit = (T_TestInitFunction)_pfnTestInit;

#define TEST_DECLARE_CLEANUP(_pfnCleanup) \
    T_TestCleanupFunction gpfnCleanup = (T_TestCleanupFunction)_pfnCleanup;

#define TEST_INFO(...) printf("  [INFO]"__VA_ARGS__)

#define TEST_ASSERT(_condition, ...)                                                 \
    do                                                                               \
    {                                                                                \
        if (!(_condition))                                                           \
        {                                                                            \
            printf("\n\033[;32m[ASSERT FAILED]\033[0m[FILE=%s][FUNC=%s][LINE=%d]\n", \
                    __FILE__, __func__, __LINE__);                                   \
            printf("\033[;32m[CONDITION]\033[0m[%s]\n", #_condition);                \
            if(sizeof(#__VA_ARGS__) - 1)TEST_INFO(__VA_ARGS__);                      \
            return -1;                                                               \
        }                                                                            \
    } while (false);                                                                 \

#endif
